docs(skills): carry the deciding question in the App / Platform Boundary - #15625
Conversation
The section stated the conclusion — business features in the app, capability in the platform — but not the test that produces it, so an app author had to already know the answer to apply it. Add the discriminator as one bullet next to that conclusion: could this be written by something that has only the metadata, and no knowledge of this company, with the two outcomes and the work each names. Rules only, no provenance narrative. Single-owner: the doctrine stays in this skill, which the other skills defer to by name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
|
ACCEPT — governed in-seat review of PR #15625, head Implemented-by: Verified in a detached compare worktree at the PR head, not from the report: one file, Two clauses of the suggested wording were dropped by measurement, and correctly: the gate counts ceil(bytes / 4), the headroom was 465 bytes and the suggestion measured 546, so the lead-in label and the trailing "do not hand-write it in the app" went instead of any existing doctrine or the ceiling; the next bullet already carries "no hand-written predicate re-implementing a platform rule". The ruled content ships whole. For the approvers and the next author: this file is now at its ceiling (headroom 1 token). Any further addition to Landing regime: governed ( Generated by Claude Code |
Fixes #15428
What changed
One bullet added to
skills/objectstack-platform/SKILL.md, section The App / Platform Boundary, directly after the bullet that states the conclusion. One file, one hunk, +6 lines, 0 deletions. No other file, no other section, no other skill; nothing under this skill'sreferences/orrules/.Before — the section stated the conclusion, but not the test that produces it, so an app author had to already know the answer to apply it:
After — the discriminator sits next to the conclusion it produces:
Budget — measured on this tree, no ceiling raise
node scripts/check-skills-token-ratchet.mjs, the gate's own line, verbatim.Before, on
origin/main6b8c67778:After, on
eb39034d7:Both readings the governed
skills/**surface owes — lines, and tokens because this surface is priced in tokens:skills/objectstack-platform/SKILL.mdskills/objectstack-platform/**(5 files)skills/**(47 files)The package delta reads +116 against the file's +115 because each row is
ceil(bytes / 4)computed over its own total; the byte delta is +461 in all three rows, and only this file changed.Fitting it in the headroom — what was trimmed, and what was not
The gate counts
ceil(utf8 bytes / 4), so the headroom is exactly 465 bytes for this file (51471 bytes now, 51936 at the ceiling). The routed suggestion measured 546 bytes. Nothing already in the section was trimmed — no existing doctrine was deleted to buy room, and the ceiling was not touched. Two clauses of the new text were dropped instead:The ruled content ships whole: the question verbatim, both outcomes, and both example lists (a discount ceiling · who a case is assigned to · how won/lost is booked; reference integrity · translation coverage · view rosters · sharing-rule coverage · CRUD round-trips · RLS probes per declared position). The amendment lands at 461 bytes.
Deliberately not in this diff
objectstack-pm-dispatchdefers to this section by name andobjectstack-upgradecarries a differently-scoped boundary; single-owner is the existing arrangement and a second copy would be a drift site.skip-changesetlabel carries that, per the precedent on sibling skill and playbook files.Gates — 21 derived families, all green at
eb39034d7Family derived on this tree, not recalled:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(change set read by the script from the merge base — 1 path), harvested with--commands, each run with its exit code captured before any pipe. Every line below is the gate's own verdict.node scripts/check-ci-filter-parity.mjs— OK: all 148 declared cross-package glob(s) (102 unique) are covered bycoreorcrosspkg, everycrosspkgentry still covers one, and thetestjob'sif:still names both filters.node scripts/check-closing-keyword-parity.mjs— check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 7572 tracked file(s), all registered).node scripts/check-closing-keyword-parity.mjs --self-test— ✓ 24 assertions, 5 mutations of the shipped parsers each driven to red.node scripts/check-comment-mask-corpus.mjs— ✓ comment-mask corpus sweep: 5964 files, 0 disagree, 0 unparseable (comparator self-test: 17 cases pass).node scripts/check-skills-token-ratchet.mjs— quoted in full above.node scripts/check-skills-token-ratchet.mjs --self-test— ✓ check-skills-token-ratchet self-test: 64 cases pass.pnpm --filter @objectstack/lint run check:doc-formula-expressions— ✓ 22 record-scoped formula example(s) across 428 files / 1371 TS blocks judged clean; ✓ 9 spec TSDoc example(s) clean; ✓ 14 field-level predicate(s) clean.pnpm --filter @objectstack/spec run check:skill-docs— ✅ Skill docs in sync.pnpm check:agent-test-spelling— ✓ 0 violations, 450 file(s) read.pnpm check:corpus-claim-drift— check-corpus-claim-drift: OK, no new claim sites beside a pinned spelling.pnpm check:cross-package-test-inputs— OK: 27 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.pnpm check:doc-authoring— ✓ doc authoring guard: 46 published skill files clean, no internal issue-id references (plus the spec-string and sibling-prose legs clean).pnpm check:driver-memory-census— check-driver-memory-census: OK, every declaration ledgered and every ledger entry live.pnpm check:nul-bytes— check-nul-bytes: OK (scanned 7565 text file(s), skipped 7 binary; no raw ASCII control bytes).pnpm check:pm-governed-merges— ✓ check-governed-merges --self-test: 263 assertions; live: the real generator declared 9 output(s) and certified this tree.pnpm check:refd-timer-probe— OK: 5959 source file(s) swept.pnpm check:role-word— check-role-word: OK, no new occurrences of the reserved word.pnpm check:skill-compatibility— ✓ 11 SKILL.md file(s) reconciled against 79 workspace packages.pnpm check:skill-frame-sync— ✓ 2 copies of the decision frame are structurally isomorphic across 2 files.pnpm check:skill-identifier-liveness— OK: Leg 1, 465 citation(s) over 46 published file(s) against 95964 implementation word tokens; Leg 2, 8 registered exhaustive section(s), 0 ledgered gap(s).pnpm check:watch-hint-literal— ✓ 58 declaration(s) across 4 rostered name(s), no unrostered spelling in the tree.check:doc-formula-expressionsfirst exited 3 withPREREQUISITE NOT MET— read as not measured, never as a finding. It named@objectstack/formula, then@objectstack/lint; both were built (through the shared verify lock) and it was re-run green. All three prerequisite-driven runs are reported here rather than dropped.The whole family was run after the final commit, so every verdict above is a reading of
eb39034d7and not of an earlier tree.Review route
node scripts/pm/check-governed-merges.mjs --test skills/objectstack-platform/SKILL.md—⛔ GOVERNED — a human merge is the review record for this PR, exit 3. Draft PR: no ready flip, no merge queue, no auto-merge, no agent approval.🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code